/*------------------------------------------------------*/
/*                                                      */
/* Copyright (C)	sky-mobi.com                        */
/* All rights reserved                                  */
/*                                                      */
/* Author   tristan.yang                                */
/*                                                      */
/* History  2011-12-05 created                          */
/*                                                      */
/*------------------------------------------------------*/

#ifndef __MG_CONNECT_H__
#define __MG_CONNECT_H__

#include "RtBase.h"
#include "RtTimeValue.h"
#include "RtUtilTemplates.h"
#include "connprovider.h"
#include "tsbase.h"
#include "tlv12.h"
#include "cvtlvdef.h"

class CMgConnectSink
{
public:
	// report source update info
	virtual void OnDisconnect(LPVOID pConn, const TransportAddress& refAddr) = 0;
	virtual ~CMgConnectSink() {}
};

class CMgMgrSink;
class CMgConnect
: public CRtTimerWrapperSink
, public IConnectionSink
, public CRtReferenceControlSingleThread
{
public:
	CMgConnect(CMgMgrSink* pmgrsink, CMgConnectSink* psink, IConnection* pConn);
	virtual ~CMgConnect();

	RtResult Initialize(const VecProgram& refProV);
	RtResult GetOption(DWORD aOption, LPVOID lpData);
	RtResult Disconnect(DWORD aReason);

	// from CRtTimerWrapperSink
	virtual void OnTimer(CRtTimerWrapper* aID);

	RtResult MgProgramUpdate(const VecProgram& refProV);
	RtResult MgProgramDelete(const VecProgram& refProV);
	RtResult GetAllStreams(ProgramDetailMap*& refMap);
protected: 

	// from IConnectionSink
	virtual void OnReceiveData(CRtMessageBlock& aData, IConnection* pConn);
	virtual void OnDisconnect(RtResult aReason, IConnection* pConn); 
	virtual void OnSend(IConnection* pConn);
	
private:
	void SaveRawData(LPBYTE pbuf, int isize, int iframe);
	void Save264Frame(LPCSTR filename, LPBYTE pFrame, int isize, int idx);
	
	void SendTlv(uint8_t* pbuf, uint32_t ulen, uint16_t ucmd, int16_t iresult);
	void OnReceiveTlv(LPBYTE pdata, INT ilen);
	void HandleMediaOutStreamInfoResp(LPBYTE pdata, INT ilen);
	void HandleOpenChannelResp(LPBYTE pdata, INT ilen);
	void HandleCloseChannelNotify(LPBYTE pdata, INT ilen);
	void HandleMediaData(LPBYTE pdata, INT ilen);
	void HandleMgMediaDataNotify(const CRtString& refSrcKey, 
								 const st_MGavhead& refhead, 
								 LPBYTE pdate, 
								 DWORD dwlen);

	RtResult SubProgram(const st_MgProgram& refMP);
	RtResult UnSubProgram(const st_MgProgram& refMP);
	RtResult StopProgram(const st_MgProgram& refMP);
	RtResult GetProgramStreamInfo(const CRtString& ref);
	
	LPVOID FindProgram(const CRtString& refSrcKey);
	BOOL FindIfNeedUnSub(const st_MgProgram& refProm, const VecProgram& refProV);
	BOOL FindIfNeedSub(const st_MgProgram& refProm);

	DWORD GetHeadLen(){return sizeof(RESP_CMD_HEAD);}

private:
	RtResult SendMsg(CRtMessageBlock& );
	RtResult SendData(CRtMessageBlock &aData);
	void TrySendMessages();
	std::list<CRtMessageBlock*>	m_CacheMsgList;
	BOOL						m_bCanSend;

private:
	CMgMgrSink*			m_pMgrSink;
	CMgConnectSink*		m_pSink;

	ProgramDetailMap	m_mapProgram;

	CRtAutoPtr<IConnection> m_pConnect;

	DWORD				m_dwChannelId;
	CRtString			m_strMsgBuf;
	Trans_Status		m_stTrans;

	FILE*				m_p264File[26];
};

#endif//__MG_CONNECT_H__
